package com.fj.order.web;

import apache.rocketmq.v2.Message;
import com.alibaba.fastjson.JSON;
import com.fj.domain.Order;
import com.fj.domain.Product;
import com.fj.order.feign.ProductService;
import com.fj.order.service.OrderService;
import com.fj.order.web.dto.CreateOrderDto;
import com.fj.order.web.dto.FjResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.MarkerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;
import java.util.Random;

/**
 * @author fj
 * @date 2024/3/12 00:31
 */
@Slf4j
@RestController
@RequestMapping(value = "/order")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Resource
    private ProductService productService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Value("${param.mq.orderTopic}")
    private String orderTopic;
    /**
     * 硬编码写死IP+端口
     */
//    @RequestMapping(value = "/create", method = RequestMethod.POST)
//    public Order order(@RequestBody CreateOrderDto dto){
//        Product product = restTemplate.getForObject("http://127.0.0.1:8200/product/1", Product.class);
//        log.info(JSON.toJSONString(product));
//        Order order = new Order();
//        order.setPid(dto.getPid());
//        order.setNumber(dto.getNumber());
//        order.setPname(product.getPname());
//        order.setPprice(product.getPprice().toString());
//        return orderService.order(order);
//    }

    /**
     * 2.通过注册中心获取IP+端口
     * @param dto
     * @return
     */
//    @RequestMapping(value = "/create", method = RequestMethod.POST)
//    public Order order(@RequestBody CreateOrderDto dto){
//        List<ServiceInstance> instances = discoveryClient.getInstances("shop-product");
//        ServiceInstance instance = instances.get(0);
//        log.info("通过注册中心获取实例|{}:{}",instance.getHost(),instance.getPort());
//        Product product = restTemplate.getForObject(String.format("http://%s:%s/product/1",instance.getHost(),instance.getPort()), Product.class);
//        log.info(JSON.toJSONString(product));
//        Order order = new Order();
//        order.setPid(dto.getPid());
//        order.setNumber(dto.getNumber());
//        order.setPname(product.getPname());
//        order.setPprice(product.getPprice().toString());
//        return orderService.order(order);
//    }

    /**
     * 自定义随机算法实现【客户端】负载均衡
     * @param dto
     * @return
     */
//    @RequestMapping(value = "/create", method = RequestMethod.POST)
//    public Order order(@RequestBody CreateOrderDto dto){
//        List<ServiceInstance> instances = discoveryClient.getInstances("shop-product");
//        int i = new Random().nextInt(2);
//        log.info("随机到负载{}",i);
//        ServiceInstance instance = instances.get(i);
//        log.info("通过注册中心获取实例|{}:{}",instance.getHost(),instance.getPort());
//        Product product = restTemplate.getForObject(String.format("http://%s:%s/product/1",instance.getHost(),instance.getPort()), Product.class);
//        log.info(JSON.toJSONString(product));
//        Order order = new Order();
//        order.setPid(dto.getPid());
//        order.setNumber(dto.getNumber());
//        order.setPname(product.getPname());
//        order.setPprice(product.getPprice().toString());
//        return orderService.order(order);
//    }

    /**
     * loadbalancer实现负载均衡
     * @param dto
     * @return
     */
//    @RequestMapping(value = "/create", method = RequestMethod.POST)
//    public Order order(@RequestBody CreateOrderDto dto){
//        ServiceInstance choose = loadBalancerClient.choose("shop-product");
//        log.info("负载均衡到|{}:{}",choose.getHost(),choose.getPort());
//        Product product = restTemplate.getForObject(String.format("http://%s:%s/product/1",choose.getHost(),choose.getPort()), Product.class);
//        log.info(JSON.toJSONString(product));
//        Order order = new Order();
//        order.setPid(dto.getPid());
//        order.setNumber(dto.getNumber());
//        order.setPname(product.getPname());
//        order.setPprice(product.getPprice().toString());
//        return orderService.order(order);
//    }

    /**
     * Ribbon实现负载均衡
     * @param dto
     * @return
     */
//    @RequestMapping(value = "/create", method = RequestMethod.POST)
//    public Order order(@RequestBody CreateOrderDto dto){
//        log.info("通过Ribbon调用下游服务");
//        Product product = restTemplate.getForObject("http://shop-product/product/1", Product.class);
//        log.info(JSON.toJSONString(product));
//        Order order = new Order();
//        order.setPid(dto.getPid());
//        order.setNumber(dto.getNumber());
//        order.setPname(product.getPname());
//        order.setPprice(product.getPprice().toString());
//        return orderService.order(order);
//    }

    /**
     * 通过feign调用
     * @param dto
     * @return
     */
//    @RequestMapping(value = "/create", method = RequestMethod.POST)
//    public FjResponse<Object> order(@RequestBody CreateOrderDto dto){
//        log.info("通过feign调用下游服务");
//        Product product = productService.getProduct(dto.getPid());
//        if (product.getPid()==null){
//            return FjResponse.fail("下单失败");
//        }
//        log.info(JSON.toJSONString(product));
//        Order order = new Order();
//        order.setPid(dto.getPid());
//        order.setNumber(dto.getNumber());
//        order.setPname(product.getPname());
//        order.setPprice(product.getPprice().toString());
//        orderService.order(order);
//        log.info(MarkerFactory.getMarker("xpf"),"发送MQ消息");
//        SendResult sendResult = rocketMQTemplate.syncSend(orderTopic, order);
//        log.info(MarkerFactory.getMarker("xpf"),sendResult.toString());
//        return FjResponse.ok(order);
//    }
//    private int count = 0;
//
//    @GetMapping(value = "message1")
//    public String message1(){
//        if (++count%3==0){
//            throw new RuntimeException("模拟异常");
//        }
//        return "message1";
//    }
//
//    @GetMapping(value = "message2")
//    public String message2(){
//        return "message2";
//    }
//
//    @GetMapping(value = "{oid}")
//    public FjResponse<Object> getOrder(@PathVariable(value = "oid") Integer oid){
//        return orderService.getOrder(oid);
//    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public FjResponse<Object> createOrder(@RequestBody CreateOrderDto dto){
        Order order = orderService.createOrder(dto.getUid(), dto.getPid(), dto.getNumber());
        log.info(MarkerFactory.getMarker("xpf"),"发送MQ消息");
        SendResult sendResult = rocketMQTemplate.syncSend(orderTopic, order);
        log.info(MarkerFactory.getMarker("xpf"),sendResult.toString());
        return FjResponse.ok(order);
    }
}
